let logger = require("pomelo-logger").getLogger(__filename);
let DateUtil = require("../../../utils/dateUtil");
let Random = require("../../../utils/random");
let ZhuojiGameConstant = require("../../mahjong/constant/zhuojiGameConstant");
let robotStrategy = require("../../mahjong/robot/robotStrategy");
let PlayerCreator = require("./zhuojiPlayer").create;
let PriorityQueue = require('../../mahjong/utils/priorityQueue');
let RobotUtil = require("../../mahjong/robot/robotUtil");

class ZhuojiRobotService {

    constructor() {
        this.idleRobots = new Map();
        this.workingRobots = new Map();
        this.msgs = new PriorityQueue((msg1, msg2) => msg1.timeStamp - msg2.timeStamp);
        setInterval( () => this.tick(), 1000);
    }

    initialize() {
        for (let robotData of RobotUtil.robots) {
            let robot = PlayerCreator({
                account : {
                    uid : robotData.uid,
                    nickname : robotData.nickname,
                    avatar : robotData.avatar,
                    gender : robotData.gender,
                    unionid : robotData.unionid,
                    channelUid : "",
                    description : robotData.description,
                },
                balance : 0,
            }, null, null);
            robot.isRobot = 1;
            this.idleRobots.set(robotData.uid, robot);
        }
        logger.info(`this.idleRobots....: ${this.idleRobots.size}`);
    }

    tick() {
        // logger.debug(`this.idleRobots size : ${this.idleRobots.size}`);
        // logger.debug(`this.workingRobots size : ${this.workingRobots.size}`);
        // logger.debug(`tick msgs size: ${this.msgs.size()}`);
        let start = DateUtil.nowMS();
        for (let count = 0; count < 1000; count++) {
            if (this.msgs.isEmpty()) {
                break;
            }
            let msg = this.msgs.peek();
            if (msg.timeStamp > start) {
                break;
            }
            msg = this.msgs.deQueue();
            this.handleRobotMsg(msg);
        }
        // logger.debug(`tick cost time: ${DateUtil.nowMS() - start}`);
    }

    pushMsg(robotMsg) {
        robotMsg.timeStamp += Random.randRange(1 * 1000, 3 * 1000);
        this.msgs.enQueue(robotMsg);
    }

    handleRobotMsg(robotMsg) {
        let gt = robotMsg.gameTable;
        if (gt == null) {
            logger.error(`handleRobotMsg error, gt is null!`);
            return;
        }
        let player = robotMsg.player;
        if (player == null) {
            logger.error(`handleRobotMsg error, player is null!`);
            return;
        }
        let msg = robotMsg.msg;
        if ((msg.operation & ZhuojiGameConstant.MAHJONG_OPERTAION_HU) === ZhuojiGameConstant.MAHJONG_OPERTAION_HU) {
            logger.info(`robot op hu. playerUid=${player.getUid()}`);
            robotStrategy.hu(gt, player);
        } else if ((msg.operation & ZhuojiGameConstant.MAHJONG_OPERTAION_TING) === ZhuojiGameConstant.MAHJONG_OPERTAION_TING) {
            logger.info(`robot op ting. player=${player.getUid()}`);
            robotStrategy.ting(gt, player, msg.tingList[0]);
        } else if ((msg.operation & ZhuojiGameConstant.MAHJONG_OPERTAION_CANCEL) === ZhuojiGameConstant.MAHJONG_OPERTAION_GANG) {
            logger.info(`robot op cancel. player=${player.getUid()}`);
            robotStrategy.cancel(gt, player);
        } else if ((msg.operation & ZhuojiGameConstant.MAHJONG_OPERTAION_GANG) === ZhuojiGameConstant.MAHJONG_OPERTAION_GANG) {
            logger.info(`robot op gang. player=${player.getUid()}, msg=${JSON.stringify(msg)}`);
            robotStrategy.gang(gt, player, msg.gangList[0].cards[0]);
        } else if ((msg.operation & ZhuojiGameConstant.MAHJONG_OPERTAION_PENG) === ZhuojiGameConstant.MAHJONG_OPERTAION_PENG) {
            logger.info(`robot op peng. player=${player.getUid()}`);
            robotStrategy.peng(gt, player);
        } else if (msg.operation === ZhuojiGameConstant.MAHJONG_OPERTAION_CHU) {
            logger.info(`robot op chu. player=${player.getUid()}`);
            // let cardGrab = player.getCardGrab() !== 0 ? player.getCardGrab() : player.cardsInHand[0];
            robotStrategy.chu(gt, player);
        } else {
            logger.info(`invalid robot operation=0x${msg.operation.toString(16)}, playerUid=${player.getUid()}`);
        }
    }

    getRobot(gt) {
        if (this.idleRobots.size  === 0) {
            return null;
        }
        let keys = [...this.idleRobots.keys()];
        let key = keys[Random.randRange(0, keys.length - 1)];
        let robot = this.idleRobots.get(key);
        this.idleRobots.delete(key);
        this.workingRobots.set(key, robot);
        robot.balance = Random.randRange(gt.room.minStack,  gt.room.minStack * 5);
        return robot;
    }

    quitRobot(robot) {
        this.workingRobots.delete(robot.getUid());
        this.idleRobots.set(robot.getUid(), robot);
    }

    kickRobot(gt, robot) {
        this.quitRobot(robot);
        gt.leave(robot);
        gt.broadCastWithout("onPlayerLeave", {uid: robot.getUid()}, robot.getUid());
    }
}

module.exports = ZhuojiRobotService;